package com.shijie.sjoj.model.base;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import com.shijie.sjoj.model.component.LogAnsi;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 基础枚举类型序列化接口,T为子类本身
 */
public interface BaseValueEnumSerialize<T extends BaseValueEnumSerialize<T>> extends Serializable {

    /**
     * 返回默认的枚举值：Default("N/A")
     *
     * @return 默认的枚举值
     */
    T defaultInstance();

    /**
     * 从字符串值推断枚举类型，实现类应将返回值改为自己，若找不到相应枚举量则必须返回null值
     *
     * @param value 枚举类的值
     * @return 应改为BaseEnumSerialize的具体实现类
     */
    T newInstance(String value);

    /**
     * 获取枚举类型的字符串值
     * <pre>@JsonValue：指定序列化时使用的方法，枚举类型序列化为Json的方法</pre>
     *
     * @return String
     */
    @JsonValue
    String getValue();

    /**
     * 静态的从字符串值推断枚举类型，主要使用子类实例注册表进行反序列化，
     *
     * @param value 枚举类的（内部）值
     * @return BaseValueEnumSerialize
     */
    @JsonCreator
    static BaseValueEnumSerialize<? extends BaseValueEnumSerialize<?>> of(String value) {
        for (BaseValueEnumSerialize<? extends BaseValueEnumSerialize<?>> bes : InheritDefInstanceRegister.getRegister().values()) {
            if (null != bes.newInstance(value)) {
                return bes.newInstance(value);
            }
        }
        return null;
    }

    /**
     * 注册实例
     *
     * @param instance 子类实例（枚举值）
     */
    static <E extends BaseValueEnumSerialize<E>> void register(BaseValueEnumSerialize<E> instance) {
        InheritDefInstanceRegister.register(instance);
    }

    /**
     * 批量注册实例
     *
     * @param list 子类实例列表（枚举值）
     */
    static void registerAll(List<BaseValueEnumSerialize<? extends BaseValueEnumSerialize<?>>> list) {
        InheritDefInstanceRegister.registerAll(list);
    }

    /**
     * 获取子类实例（枚举值）注册表
     *
     * @return Map
     */
    static Map<String, BaseValueEnumSerialize<? extends BaseValueEnumSerialize<?>>> getRegister() {
        return InheritDefInstanceRegister.getRegister();
    }

    /**
     * 实现BaseEnumSerialize接口的子类实例（枚举（默认）值）注册器，用于序列化和反序列化
     *
     * @author ZSJ
     */
    @Slf4j
    final class InheritDefInstanceRegister {

        /**
         * 子类实例Map集合-注册表
         */
        private static final Map<String, BaseValueEnumSerialize<? extends BaseValueEnumSerialize<?>>> Beans_Map = new HashMap<>();

        /**
         * 注册实例
         *
         * @param instance 子类实例（枚举值）
         */
        public static <E extends BaseValueEnumSerialize<E>> void register(BaseValueEnumSerialize<E> instance) {
            String key = instance.getClass().getCanonicalName();
            if (!Beans_Map.containsKey(key)) {
                Beans_Map.put(key, instance.defaultInstance());
                log.info(LogAnsi.green("BaseValueEnumSerialize.InheritDefInstanceRegister_Map已注册：{}"), instance.getClass().getCanonicalName());
            }
        }

        /**
         * 批量注册实例
         *
         * @param list 子类实例列表（枚举值）
         */
        public static void registerAll(List<BaseValueEnumSerialize<? extends BaseValueEnumSerialize<?>>> list) {
            list.forEach(InheritDefInstanceRegister::register);
        }

        /**
         * 获取子类实例（枚举值）注册表
         *
         * @return Map
         */
        private static Map<String, BaseValueEnumSerialize<? extends BaseValueEnumSerialize<?>>> getRegister() {
            if (!Beans_Map.isEmpty()) {
                return new HashMap<>(Beans_Map);
            }
            log.error("BaseValueEnumSerialize.InheritDefInstanceRegister：实例注册Map表为空");
            return Map.of();
        }

    }


}
